#pragma once
#include <iostream>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Log.hpp"
#include <string>
#include <error.h>
#include <string.h>
#include "Common.hpp"
#include "InetAddr.hpp"
#include <thread>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h>
#include<functional>
#include"ThreadPool.hpp"
using namespace ThreadPoolModule;
using namespace LogModule;
using handler_t=std::function<std::string(std::string&)>;
static const uint16_t gport = 8081;

class TcpServer
{
    using task_t=std::function<void()>;
    struct ThreadData
    {
        int sockfd;
        TcpServer* server;
    };

public:
    TcpServer(handler_t handler, int port = gport) :_handler(handler), _port(port), _isruning(false)
    {
    }
    void InitServer()
    {
        // 构建sock
        _sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
        if (_sockfd < 0)
        {
            // 没有创建成功
            LOG(LogLevel::ERROR) << "socket error :" << strerror(errno);
            Die(SOCKET_ERR);
        }
        LOG(LogLevel::INFO) << "socket create success, sockfd is : " << _sockfd;
        // bind
        struct sockaddr_in add;
        memset(&add, 0, sizeof(add));
        add.sin_family = AF_INET;
        add.sin_port = ::htons(gport);
        add.sin_addr.s_addr = INADDR_ANY;
        int n = ::bind(_sockfd, CONV(&add), sizeof(add));
        if (n < 0)
        {
            LOG(LogLevel::ERROR) << "bind error:" << strerror(errno);
            Die(BIND_ERR);
        }
        LOG(LogLevel::INFO) << "bind success, sockfd is : " << _sockfd;
        // TCP协议下需要等待请求的发送,然后去建立连接
        // 请求等待
        n = ::listen(_sockfd, 8);
        if (n < 0)
        {
            LOG(LogLevel::ERROR) << "listen error" << strerror(errno);
            Die(LISTEN_ERR);
        }
        LOG(LogLevel::INFO) << "listen success, sockfd is : " << _sockfd;
    }

    static void* ThreadEntry(void* arg)
    {
        pthread_detach(pthread_self());
        ThreadData* data=(ThreadData*)arg;
        data->server->HandlerRequest(data->sockfd);
        return nullptr;
    }
    void HandlerRequest(int sockfd)
    {
        LOG(LogLevel::INFO) << "HandlerRequest, sockfd is : " << sockfd;
        std::string geass;
        while (true)
        {
            char buffer[4096];
            // ssize_t sit = ::read(sockfd, buffer, sizeof(buffer)-1);
            ssize_t sit = ::recv(sockfd, buffer, sizeof(buffer) - 1, 0);
            if (sit > 0)
            {
                buffer[sit] = 0;
                LOG(LogLevel::INFO) << buffer;
                // std::string echo_str = "echo str # ";
                // echo_str += buffer;
                geass+=buffer;
                std::string cmd_result =_handler(geass);
                if(cmd_result.empty()) continue;

                // ::write(sockfd, echo_str.c_str(), echo_str.size());
                ::send(sockfd, cmd_result.c_str(), cmd_result.size(), 0);
            }
            else if (sit == 0)
            {
                LOG(LogLevel::INFO) << "client quit";
                break;
            }
            else
            {
                break;
            }
        }

        close(sockfd);
    }
    void Start()
    {
        _isruning = true;
        while (_isruning)
        {
            struct sockaddr_in awq;
            socklen_t len=sizeof(awq);

            int sockfd = ::accept(_sockfd, CONV(&awq), &len);
            if (sockfd < 0)
            {
                LOG(LogLevel::WARNING) << "accept error: " << strerror(errno);
                continue;
            }
            LOG(LogLevel::INFO) << "accept success, sockfd is : " << sockfd;
            InetAddr addr(awq);
            LOG(LogLevel::INFO) << "client  is : " << addr.Addr();
            // vs-0
            // HandlerRequest(sockfd);

            // vs-1
            // 进程
            // pid_t pid = ::fork();
            // if (pid < 0)
            // {
            //     LOG(LogLevel::ERROR) << "fork error: " << strerror(errno);
            //     continue;
            // }
            // else if (pid == 0)
            // {
            //     // 子进程
            //     close(_sockfd);
            //     if (fork() > 0)
            //         exit(1); // 如果子进程再次fork,则退出
            //     HandlerRequest(sockfd);
            //     exit(0);
            // }

            // // 父进程
            // close(sockfd); // 关闭子进程的socket
            // LOG(LogLevel::INFO) << "fork success, pid is " << pid;

            // int ret=::waitpid(pid, NULL, 0); // 等待子进程结束
            // if(ret<0)
            // {
            //     LOG(LogLevel::ERROR) << "waitpid error: " << strerror(errno);
            // }

            //vs-2
            // 线程
            // pthread_t tid;
            // ThreadData* data=new ThreadData;
            // data->sockfd=sockfd;
            // data->server=this;
            // pthread_create(&tid,nullptr,ThreadEntry,data);

            //vs-3 线程池
            ThreadPool<task_t>::getInstance()->Equeue([this,sockfd](){
                this->HandlerRequest(sockfd);
            });

        }
        _isruning = false;
    }
    void Stop()
    {
        _isruning = false;
    }
    ~TcpServer() {}

private:
    int _sockfd;
    uint16_t _port;
    std::string _ip;
    bool _isruning;
    handler_t _handler;
};
